/**
 * @description: ts 基本使用
 * @author: huen2015
 */
// 基本类型
const name = 'huen2015'
const age = 218
const isOther = false
const unde = undefined
const nu = null

// any
const anyData: any = 4
anyData.a = 'a'

// 数组
const arr: number[] = [1, 2, 3]

// 对象
const obj: object = { key: '12' }

// 元组
const user: [string, number] = ['huen2015', 18]

// function
function add(x: number, y: number, z?: number): number {
	return x + y
}

const add1 = (x: number, y: number): number => {
	return x + y
}

const add2: (x: number, y: number, z?: number) => number = add

// 接口
interface Person {
	readonly id: string
	name: string
	age?: number
}
const tom: Person = {
	id: '01',
	name: 'tom',
	// age: 20
}

interface ISum {
	(x: number, y: number): number
}
const sum: ISum = function (x: number, y: number): number {
	return x + y
}
const sum1: ISum = (x: number, y: number): number => {
	return x + y
}

// 接口 - 索引签名
interface RandomMap {
	[propName: string]: string
}
const test: RandomMap = {
	key: 'key',
	value: 'value',
}
interface LikeArray {
	[propName: number]: string
}
const likeArray: LikeArray = ['1', '2', '3']

// duck typing - 鸭子类型（只要像鸭子，它就是鸭子）
interface FunctionWithProps {
	(x: number): number
	name: string
}
const a: FunctionWithProps = (x: number) => {
	return x
}
a.name = 'name'

// 泛型
function echo<T>(arg: T): T {
	return arg
}

function swap<T, U>(tuple: [T, U]): [U, T] {
	return [tuple[1], tuple[0]]
}

interface CountryResp {
	name: string
	area: number
	population: number
}
function withAPI<T>(url: string): Promise<T> {
	return fetch(url).then((resp) => resp.json())
}
withAPI<CountryResp>('/api/abc').then((resp) => {
	console.log('res', resp.area, resp.name, resp.population)
})

// 类型别名（不能重新开发类型以添加新属性）、keyof
type Keys = keyof CountryResp
type NameType = CountryResp['name']
type Test = {
	[key in Keys]: any
}
type CountryOpt = {
	[p in Keys]?: CountryResp[p]
}
interface IWithLength {
	length: number
}
// 泛型约束
function echoWithArr<T extends IWithLength>(arg: T): T {
	console.log(arg.length)
	return arg
}
const arrRes = echoWithArr([1, 2, 3])
const str = echoWithArr('123')
const objRes = echoWithArr({ length: 123, width: 'hello' })

// never、类型约束、条件约束
type NonType<T> = T extends null | undefined ? never : T
let demo1: NonType<number>
let demo2: NonType<null>

// 交叉类型
interface IName {
	name: string
}
type IPerson = IName & { age: number }
const person: IPerson = { name: 'hello', age: 12 }

// 联合类型、类型断言
let numberOrString: number | string
function getLength(input: number | string) {
	const str = input as string
	if (str.length) {
		return str.length
	} else {
		const number = input as number
		return number.toString().length
	}
}

// Partial  type Partial<T> = { [P in keyof T]?: T[P] | undefined; }
type PersonOptional = Partial<IPerson>
const personPartial: PersonOptional = { name: '12' }

export {}
